import { Action } from '@ngrx/store';
import { User, Project } from '../domain/index';

export interface UserProject {
    user: User;
    projectId: string;
}

/**
 * For each action type in an action group, make a simple
 * enum object for all of this group's action types.
 */
export enum UserActionTypes {
    ADD = '[User] Add User Project',
    ADD_SUCCESS = '[User] Add User Project Success',
    ADD_FAIL = '[User] Add User Project Fail',
    UPDATE = '[User] Update User Project ',
    UPDATE_SUCCESS = '[User] Update  User Project Success',
    UPDATE_FAIL = '[User] Update User Project  Fail',
    DELETE = '[User] Delete User Project ',
    DELETE_SUCCESS = '[User] Delete User Project  Success',
    DELETE_FAIL = '[User] Delete User Project  Fail',
    LOAD = '[User] Load Users By Projects',
    LOAD_SUCCESS = '[User] Load Users By Projects Success',
    LOAD_FAIL = '[User] Load Users By Projects Fail',
    SEARCH = '[User] Search',
    SEARCH_SUCCESS = '[User] Search Success',
    SEARCH_FAILE = '[User] Search Fail',
}

/**
 * Every action is comprised of at least a type and an optional
 * payload. Expressing actions as classes enables powerful
 * type checking in reducer functions.
 */
export class UserAddAction implements Action {
    readonly type = UserActionTypes.ADD;
    constructor(public payload: UserProject) { }
}

export class UserAddSuccessAction implements Action {
    readonly type = UserActionTypes.ADD_SUCCESS;
    constructor(public payload: User) { }
}
export class UserAddFailAction implements Action {
    readonly type = UserActionTypes.ADD_FAIL;
    constructor(public payload: string) { }
}

export class UserUpdateAction implements Action {
    readonly type = UserActionTypes.UPDATE;
    constructor(public payload: Project) { }
}

export class UserUpdateSuccessAction implements Action {
    readonly type = UserActionTypes.UPDATE_SUCCESS;
    constructor(public payload: User[]) { }
}
export class UserUpdateFailAction implements Action {
    readonly type = UserActionTypes.UPDATE_FAIL;
    constructor(public payload: string) { }
}

export class UserDeleteAction implements Action {
    readonly type = UserActionTypes.DELETE;
    constructor(public payload: UserProject) { }
}

export class UserDeleteSuccessAction implements Action {
    readonly type = UserActionTypes.DELETE_SUCCESS;
    constructor(public payload: User) { }
}

export class UserDeleteFailAction implements Action {
    readonly type = UserActionTypes.DELETE_FAIL;
    constructor(public payload: string) { }
}

export class UserLoadAction implements Action {
    readonly type = UserActionTypes.LOAD;
    constructor(public payload: string) { }
}

export class UserLoadSuccessAction implements Action {
    readonly type = UserActionTypes.LOAD_SUCCESS;
    constructor(public payload: User[]) { }
}
export class UserLoadFailAction implements Action {
    readonly type = UserActionTypes.LOAD_FAIL;
    constructor(public payload: string) { }
}
export class UserSearchAction implements Action {
    readonly type = UserActionTypes.SEARCH;
    constructor(public payload: string) { }
}

export class UserSearchSuccessAction implements Action {
    readonly type = UserActionTypes.SEARCH_SUCCESS;
    constructor(public payload: User[]) { }
}
export class UserSearchFailAction implements Action {
    readonly type = UserActionTypes.SEARCH_FAILE;
    constructor(public payload: string) { }
}

/**
 * Export a type alias of all actions in this action group
 * so that reducers can easily compose action types
 */
export type UserActions
    = UserAddAction
    | UserAddSuccessAction
    | UserAddFailAction
    | UserUpdateAction
    | UserUpdateSuccessAction
    | UserUpdateFailAction
    | UserDeleteAction
    | UserDeleteSuccessAction
    | UserDeleteFailAction
    | UserLoadAction
    | UserLoadSuccessAction
    | UserLoadFailAction
    | UserSearchAction
    | UserSearchSuccessAction
    | UserSearchFailAction;
